import { defineComponent, computed, ref, reactive, watchEffect, onMounted, onBeforeUnmount, createVNode, createTextVNode } from 'vue';
import Tag from '../Tag/index.js';
import Popover from '../Popover/index.js';
import { uuidv4 } from '../utils/assist.js';

const TagGroup = /* @__PURE__ */ defineComponent({
  name: 'TagGroup',
  props: {
    data: {
      type: Array,
      default: []
    },
    closable: {
      type: Boolean,
      default: false
    },
    max: {
      type: [Number, String]
    },
    showMore: {
      type: Boolean,
      default: false
    },
    moreCloseable: {
      type: Boolean
    },
    tooltipAlign: {
      type: String,
      default: 'top'
    },
    tooltipTheme: {
      type: String,
      default: 'light'
    },
    tooltipTrigger: {
      type: String,
      default: 'hover'
    },
    tooltipStyle: {
      type: Object
    },
    size: {
      type: String,
      default: 'small'
    },
    extra: {
      type: Object
    }
  },
  emits: ['close'],
  setup(props, {
    emit
  }) {
    const classList = computed(() => ({
      'cm-tag-group': true,
      'cm-tag-group-overflow': props.max === 'auto'
    }));
    const wrap = ref();
    const showStyle = {
      position: '',
      height: '',
      'point-event': '',
      overflow: ''
    };
    const hideStyle = {
      position: 'absolute',
      height: '0px',
      'point-event': 'none',
      overflow: 'hidden'
    };
    const store = reactive({
      list: [],
      show: [],
      hide: []
    });
    const onClose = (item, e) => {
      const newList = store.list.filter(aitem => {
        return aitem.id !== item.id;
      });
      store.list = newList;
      emit('close', e);
      queueMicrotask(() => {
        onSizeChange();
      });
    };
    watchEffect(() => {
      const arr = props.data.map(item => {
        if (item.id === undefined) {
          item.id = uuidv4();
        }
        if (props.max === 'auto') {
          item._style = {
            ...hideStyle
          };
        }
        return item;
      });
      store.list = arr;
      const show = [];
      const hide = [];
      if (props.max === 'auto') {
        store.hide = hide;
        queueMicrotask(() => {
          onSizeChange();
        });
      } else {
        const max = props.max ?? arr.length;
        for (let i = 0; i < max; i++) {
          arr[i] && show.push(arr[i]);
        }
        const length = arr.length;
        for (let j = max; j < length; j++) {
          hide.push(arr[j]);
        }
        store.show = show;
        store.hide = hide;
      }
    });

    // watch(() => store.list, (list: TagConfig[]) => {
    //     console.log(222);

    // });

    // 隐藏
    const hideTag = index => {
      if (!store.hide.includes(store.list[index])) {
        store.hide.push(store.list[index]);
      }
      // store.list[index]._style = {...hideStyle};
    };

    // 显示
    const showTag = index => {
      // 已经隐藏的从hide中移除
      const idx = store.hide.indexOf(store.list[index]);
      if (idx > -1) {
        store.hide.splice(idx, 1);
      }
      // store.list[index]._style = {...showStyle};
    };
    const onSizeChange = () => {
      if (props.max !== 'auto') {
        return;
      }
      const wrapRect = wrap.value.getBoundingClientRect();
      const tags = wrap.value.querySelectorAll('.cm-tag:not(.cm-tag-more)');
      let w = 0;
      const more = wrap.value.querySelector('.cm-tag-more');
      const shows = [];
      const hides = [];
      tags.forEach((tag, index) => {
        const moreRect = more?.getBoundingClientRect();
        const moreWidth = moreRect ? 5 + moreRect?.width : 25;
        const tagWidth = tag.offsetWidth;
        if (w + (index === 0 ? 0 : 5) + tagWidth + moreWidth < wrapRect.width) {
          w = w + (index === 0 ? 0 : 5) + tagWidth;
          if (tag.style.height === '0px') {
            shows.push(index);
          }
        } else {
          hides.push(index);
        }
      });
      // 批量修改
      shows.forEach(index => {
        showTag(index);
      });
      hides.forEach(index => {
        hideTag(index);
      });
    };
    onMounted(() => {
      const ob = new ResizeObserver(() => {
        onSizeChange();
      });
      if (props.max === 'auto') {
        ob.observe(wrap.value);
      }
      onBeforeUnmount(() => {
        ob.disconnect();
      });
    });
    return () => createVNode("div", {
      "class": classList.value,
      "ref": wrap
    }, [props.max === 'auto' ? store.list.map(item => {
      return createVNode(Tag, {
        "closable": props.closable,
        "style": store.hide.indexOf(item) > -1 ? hideStyle : showStyle,
        "size": props.size,
        "theme": item.theme,
        "avatar": item.avatar,
        "onClose": e => {
          onClose(item, e);
        }
      }, {
        default: () => [item.title]
      });
    }) : store.show.map(item => {
      return createVNode(Tag, {
        "closable": props.closable,
        "size": props.size,
        "theme": item.theme,
        "avatar": item.avatar,
        "onClose": e => {
          onClose(item, e);
        }
      }, {
        default: () => [item.title]
      });
    }), store.hide.length ? props.showMore ? createVNode(Popover, {
      "class": "cm-tag-group-more-popover",
      "align": props.tooltipAlign,
      "arrow": true,
      "theme": props.tooltipTheme,
      "trigger": props.tooltipTrigger,
      "style": props.tooltipStyle,
      "content": createVNode("div", {
        "class": "cm-tag-group-more-wrap"
      }, [store.hide.map(item => {
        return createVNode(Tag, {
          "size": props.size,
          "theme": item.theme,
          "closable": props.moreCloseable,
          "onClose": e => {
            onClose(item, e);
          },
          "avatar": item.avatar
        }, {
          default: () => [item.title]
        });
      })])
    }, {
      default: () => [createVNode(Tag, {
        "class": "cm-tag-more"
      }, {
        default: () => [createVNode("span", null, [createTextVNode("+")]), store.hide.length]
      })]
    }) : createVNode(Tag, {
      "class": "cm-tag-more"
    }, {
      default: () => [createVNode("span", null, [createTextVNode("+")]), store.hide.length]
    }) : null, props.extra]);
  }
});

export { TagGroup as default };
